﻿using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using log4net;
using Newtonsoft.Json;
using Rvt2ifcTool.Common;
using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using ILog = log4net.ILog;

namespace Rvt2ifcTool
{
	internal class RevitHandler : IExternalEventHandler
	{
		public static ILog log { get { return LogManager.GetLogger(typeof(RevitHandler)); } }

		public string gRvtPath = "";
		public string gScriptName = "";
		public string mOutputGuid = "";
		public string mModelUuid = "";
		public string mProjectUuid = "";
		public string mModelName = "";
		public string gModelPath = "";
		public string gBaseDirectory = "";
		private UIApplication _uiapp;
		private Document _docToClose; // 需要关闭的旧文档

		public void Execute(UIApplication app)
		{
			_uiapp = app;
			XeokitUtils.BaseDirectory = gBaseDirectory;
			string projectDirectory = XeokitUtils.GetProjectDirectory(gBaseDirectory, mProjectUuid);
			// 打开模型
			UIDocument uiDoc = OpenModel(gRvtPath, app);
			if (uiDoc != null)
			{
				string ifcPath = Path.Combine(Path.GetTempPath(), "xeokit", mOutputGuid + ".ifc");
				if (ExportIfc(uiDoc.Document, ifcPath))
				{
					XeokitUtils.ExportXkt(ifcPath,
											projectDirectory,
											gScriptName,
											 mOutputGuid,
											 mModelUuid,
											 mModelName,
											 mProjectUuid);
				}
			}

			// 让 Revit 在空闲时关闭旧文档
			if (_docToClose != null && _docToClose.IsValidObject)
			{
				app.Idling += OnIdlingCloseDocument;
			}
		}

		private void OnIdlingCloseDocument(object sender, IdlingEventArgs e)
		{
			_uiapp.Idling -= OnIdlingCloseDocument; // 取消订阅事件
			try
			{
				if (_docToClose != null && _docToClose.IsValidObject)
				{
					_docToClose.Close(false); // 关闭旧文档（false 表示不保存）
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.ToString());
				log.Error(ex);
			}
		}

		private bool ExportIfc(Document doc, string exportPath)
		{
			try
			{
				IFCExportOptions options = new IFCExportOptions
				{
					FileVersion = IFCVersion.IFC2x3,
					ExportBaseQuantities = true
				};

				using (Transaction transaction = new Transaction(doc, "Export IFC"))
				{
					transaction.Start();
					try
					{
						string dir = Path.GetDirectoryName(exportPath);
						if (!Directory.Exists(dir))
						{
							Directory.CreateDirectory(dir);
						}
						doc.Export(Path.GetDirectoryName(exportPath), Path.GetFileName(exportPath), options);
						log.Info("导出IFC成功！");
						transaction.Commit();
						return true;
					}
					catch (Exception ex)
					{
						log.Error(ex);
						transaction.RollBack();
						return false;
					}
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.ToString());
				log.Error(ex);
				return false;
			}
		}

		private UIDocument OpenModel(string path, UIApplication uiapp)
		{
			try
			{
				OpenOptions openOptions = new OpenOptions
				{
					AllowOpeningLocalByWrongUser = false,
					DetachFromCentralOption = DetachFromCentralOption.DetachAndPreserveWorksets
				};

				WorksetConfiguration openWorksetsConfiguration = new WorksetConfiguration(WorksetConfigurationOption.OpenAllWorksets);
				openOptions.SetOpenWorksetsConfiguration(openWorksetsConfiguration);

				// 记录当前文档
				_docToClose = uiapp.ActiveUIDocument?.Document;

				// 打开新模型
				ModelPath modelPath = ModelPathUtils.ConvertUserVisiblePathToModelPath(path);
				UIDocument uidoc = uiapp.OpenAndActivateDocument(modelPath, openOptions, false);

				// 旧文档将在 Idling 事件中关闭
				return uidoc;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.ToString());
				log.Error(ex);
				return null;
			}
		}





		public string GetName()
		{
			return "打开模型并导出IFC";
		}
	}
}